<script setup>
import { ref, onMounted } from 'vue'
import { Map, View } from 'ol'
import TileLayer from 'ol/layer/Tile'                // 瓦片图层
import XYZ from 'ol/source/XYZ'
import {fromLonLat} from "ol/proj.js";
import {easeIn, easeOut} from "ol/easing.js";

const map = ref(null)
//注意参考系
const beijing = fromLonLat([116.3898468017578, 39.91026292816486], "EPSG:4326");
const guangzhou = fromLonLat([113.24981689453125, 23.126468438108688], "EPSG:4326");

/**
 * 初始化地图
 * 创建地图实例并加载天地图瓦片服务
 */
const initMap = () => {
  map.value = new Map({
    target: 'map',  // 挂载到id为'map'的DOM元素
    layers: [
      new TileLayer({
        source: new XYZ({
          url: 'http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d30d1c34260f2edc72b25f9985e2fd69'
        })
      })
    ],
    view: new View({
      projection: 'EPSG:4326',  // 使用WGS84坐标系
      zoom: 12,                 // 初始缩放级别
      center: [113.24981689453125, 23.126468438108688]  // 初始中心点坐标
    })
  });
}

// 旋转动画
const rotateLocation = ()=>{
  const view = map.value.getView();
  const center = view.getCenter();
  // 可以传递多个对象代表不同的过程
  view.animate({
    //动画结束时的视图中心,即当前视图中心同目标视图中心连线的中心点
    center: center,
    rotation: Math.PI, //动画结束时的旋转角度，即180度
    easing: easeIn//按每一帧动画控制的动画速度，即开始缓慢并逐渐加快速度
  },
      // 结束位置
      {
        center: beijing,//动画结束时的视图中心
        rotation: 2 * Math.PI,//动画结束时的旋转角度，即360度回正
        easing: easeOut//按每一帧动画控制的动画速度，即开始快速并逐渐减速
      }
  )
}

const elasticLocation = ()=>{
  function elastic(t) {
    //函数-10*sin(t-0.075)**t*t+1
    return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;
  }
  const view = map.value.getView();
  view.animate({
    center: beijing,
    duration: 2000,
  //按每一帧动画控制的动画持续时间函数
    easing: elastic
  })
}

// 反弹定位
const reboundLocation = ()=>{
  // 反弹值
  function bounce(t) {
    var s = 7.5625, p = 2.75, l;
    if (t < (1 / p)) {
      l = s * t * t;
    } else {
      if (t < (2 / p)) {
        t -= (1.5 / p);
        l = s * t * t + 0.75;
      } else {
        if (t < (2.5 / p)) {
          t -= (2.25 / p);
          l = s * t * t + 0.9375;
        } else {
          t -= (2.625 / p);
          l = s * t * t + 0.984375;
        }
      }
    }
    return l;
  }
  let view = map.value.getView();
  view.animate({
    center: guangzhou,///动画结束时的视图中心
    duration: 2000,//动画的持续时间（以毫秒为单位）
    easing: bounce//按每一帧动画控制的动画持续时间函数
  });
}
const flyLocation = ()=>{
  const view = map.value.getView();
  const duration = 2000;
  const zoom = view.getZoom();

  //动画完成的回调函数
  function callback(complete) {
    console.log("动画完成" + complete)
  }

  // 这是飞往广州的动画
  view.animate({
    duration,
    center: guangzhou,
  },callback);

  //第二个动画 这是缩放的动画
  view.animate({
    zoom: zoom - 1,
    duration: duration / 2
  }, {
    zoom: zoom,
    duration: duration / 2
  }, callback);
}
const aroundRotate = ()=>{
  let view = map.value.getView();
  const rotation = view.getRotation();
  view.animate(
      //第一个过程
      {
        rotation: rotation + Math.PI,//第一次动画旋转角度
        anchor: guangzhou,//自旋的中心点
        easing: easeIn////按每一帧动画控制的动画速度，即开始缓慢并逐渐加快速度
      },
      //第二个过程
      {
        rotation: rotation + 2 * Math.PI,//动画结束时的旋转角度，即360度回正
        anchor: guangzhou,// 旋转中心点
        easing: easeOut///按每一帧动画控制的动画速度，即开始快速并逐渐减速
      });
}

// 组件挂载时初始化地图
onMounted(initMap);
</script>

<template>
  <!--地图挂载dom-->
  <div id="map">
    <div class="MapTool">
      <el-row>
        <el-button type="primary" @click.stop.prevent="rotateLocation">旋转定位</el-button>
        <el-button type="success" @click.stop.prevent="elasticLocation">弹性定位</el-button>
        <el-button type="info" @click.stop.prevent="reboundLocation">反弹定位</el-button>
        <el-button type="warning" @click.stop.prevent="flyLocation">飞行定位</el-button>
        <el-button type="danger" @click.stop.prevent="aroundRotate">围绕旋转</el-button>
      </el-row>
    </div>
  </div>
</template>

<style scoped>
#map {
  width: 100%;
  height: 100%;
}

.MapTool {
  position: absolute;
  top: .5em;
  right: .5em;
  z-index: 9999;
}
</style>